import path from 'path'
import fs from 'fs-extra'
import glob from 'glob'
import { optimize } from 'svgo'
import { JSDOM } from 'jsdom'
import { toKebabCase, toPascalCase } from '../util/convert-case'
import svgoConfig from './config'
import paths from './paths'
import { getDmyVueIcon, getComponentIndex, getIconVue, getIndex, getType } from './template'

interface IconData {
  title: string
  type: string
  list: Array<{
    name: string
    componentName: string
    path: string
  }>
}

const root = process.cwd()

const maps: Record<string, string> = {
  direction: '方向指示类图标',
  tips: '提示建议类图标',
  interactiveButton: '交互按钮类图标',
  edit: '编辑类图标',
  media: '影音类图标',
  logo: '商标类图标',
  general: '通用类图标',
}

function getSVGData(): IconData[] {
  const data: IconData[] = []
  for (const key of Object.keys(maps)) {
    const iconData: IconData = {
      title: maps[key],
      type: key,
      list: [],
    }
    const files = glob.sync(`${toKebabCase(key)}/**/*.svg`, {
      cwd: paths.iconSvgs,
      absolute: true,
    })
    console.log(paths.iconSvgs)
    for (const filePath of files) {
      const name = `icon-${path.basename(filePath, '.svg')}`
      iconData.list.push({
        name,
        componentName: `${toPascalCase(name)}`,
        path: filePath,
      })
    }
    data.push(iconData)
  }

  return data
}

async function buildIconComponent(data: IconData[]) {
  for (const iconData of data) {
    for (const item of iconData.list) {
      const svgFile = fs.readFileSync(item.path, 'utf8')
      const optimizedSvg = optimize(svgFile, { path: item.path, ...svgoConfig })
      if ('data' in optimizedSvg) {
        const svgEl = JSDOM.fragment(optimizedSvg.data).firstElementChild
        if (svgEl) {
          fs.outputFile(
            path.resolve(paths.iconComponents, `${item.name}/index.vue`),
            getIconVue({
              name: item.name,
              componentName: item.componentName,
              svgHtml: svgEl.outerHTML,
            }),
            e => {
              if (e) {
                console.log(`Build ${item.componentName} Failed: ${e}`)
              } else {
                console.log(`Build ${item.componentName} Success!`)
              }
            }
          )
        }
      }

      const indexContent = getComponentIndex({ name: item.name, componentName: item.componentName })
      fs.outputFile(path.resolve(paths.iconComponents, `${item.name}/index.ts`), indexContent, err => {
        if (err) {
          console.log(`Build ${item.componentName} Failed: ${err}`)
        } else {
          console.log(`Build ${item.componentName} Success!`)
        }
      })
    }
  }
}

function buildIndex(data: IconData[]) {
  const imports = []
  const exports = []
  const components = []

  for (const iconData of data) {
    for (const item of iconData.list) {
      components.push(item.componentName)
      imports.push(`import { ${item.componentName} } from './${item.name}'`)
      exports.push(`export * from './${item.name}'`)
    }
  }

  const dmyContent = getDmyVueIcon({ imports, components })
  const indexContent = getIndex({ exports })

  /*
  fs.outputFile(path.resolve(paths.iconComponents, 'index.ts'), dmyContent, err => {
    if (err) {
      console.log(`Build DmyVueIcon Failed: ${err}`)
    } else {
      console.log('Build DmyVueIcon Success!')
    }
  })
  */

  /* fs.outputFile(path.resolve(paths.iconComponents, 'index.ts'), indexContent, err => {
    if (err) {
      console.log(`Build Index Failed: ${err}`)
    } else {
      console.log('Build Index Success!')
    }
  }) */

  fs.outputFile(path.resolve(paths.icon, 'icons.json'), JSON.stringify(data, null, 2), err => {
    if (err) {
      console.log(`Build JSON Failed: ${err}`)
    } else {
      console.log('Build JSON Success!')
    }
  })
}

function buildType(data: IconData[]) {
  const exports = []
  for (const iconData of data) {
    for (const item of iconData.list) {
      exports.push(`${item.componentName}: typeof import('@idmy/ui/es/icon')['${item.componentName}']`)
    }
  }

  const typeContent = getType({ exports })

  fs.outputFile(path.resolve(paths.iconComponents, 'icon-components.ts'), typeContent, err => {
    if (err) {
      console.log(`Build Type Failed: ${err}`)
    } else {
      console.log('Build Type Success!')
    }
  })
}

export default async () => {
  const data = getSVGData()
  await buildIconComponent(data)
  buildIndex(data)
  buildType(data)
}
